package com.harmony.pilot.llm.service.impl;

import com.harmony.pilot.common.dto.LLMRequest;
import com.harmony.pilot.common.exception.ServiceException;
import com.harmony.pilot.llm.provider.LLMProvider;
import com.harmony.pilot.llm.provider.OpenAIProvider;
import com.harmony.pilot.llm.provider.HuaweiProvider;
import com.harmony.pilot.llm.provider.CustomProvider;
import com.harmony.pilot.llm.service.LLMService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * LLM服务实现
 */
@Slf4j
@Service
public class LLMServiceImpl implements LLMService {
    
    private final Map<String, LLMProvider> providers;
    private String currentProvider;
    
    public LLMServiceImpl(@Value("${llm.default-provider}") String defaultProvider,
                          OpenAIProvider openAIProvider,
                          HuaweiProvider huaweiProvider,
                          CustomProvider customProvider,
                          com.harmony.pilot.llm.provider.GLM4Provider glm4Provider) {
        this.providers = new HashMap<>();
        this.providers.put("openai", openAIProvider);
        this.providers.put("huawei", huaweiProvider);
        this.providers.put("custom", customProvider);
        this.providers.put("glm4", glm4Provider);
        this.currentProvider = defaultProvider;
        
        log.info("LLM Service initialized with provider: {}", defaultProvider);
    }
    
    @Override
    @Cacheable(value = "llm-generate", key = "#request.prompt")
    public Map<String, Object> generate(LLMRequest request) {
        log.info("Generating text with LLM");
        
        LLMProvider provider = getProvider();
        String result = provider.generate(request);
        
        Map<String, Object> response = new HashMap<>();
        response.put("code", result);
        response.put("provider", currentProvider);
        response.put("model", request.getModel() != null ? request.getModel() : provider.getDefaultModel());
        
        return response;
    }
    
    @Override
    @Cacheable(value = "llm-complete", key = "#request.prompt")
    public Map<String, Object> complete(LLMRequest request) {
        log.info("Completing code with LLM");
        
        // 为补全任务调整参数
        if (request.getTemperature() == null || request.getTemperature() > 0.5) {
            request.setTemperature(0.3);
        }
        
        LLMProvider provider = getProvider();
        String result = provider.complete(request);
        
        Map<String, Object> response = new HashMap<>();
        response.put("completion", result);
        response.put("provider", currentProvider);
        
        return response;
    }
    
    @Override
    public Map<String, Object> analyze(LLMRequest request) {
        log.info("Analyzing code with LLM");
        
        // 为分析任务设置低温度
        if (request.getTemperature() == null) {
            request.setTemperature(0.2);
        }
        
        LLMProvider provider = getProvider();
        String result = provider.analyze(request);
        
        Map<String, Object> response = new HashMap<>();
        response.put("analysis", result);
        response.put("provider", currentProvider);
        
        return response;
    }
    
    @Override
    public Map<String, Object> chat(LLMRequest request) {
        log.info("Chatting with LLM");
        
        LLMProvider provider = getProvider();
        String result = provider.chat(request);
        
        Map<String, Object> response = new HashMap<>();
        response.put("message", result);
        response.put("provider", currentProvider);
        
        return response;
    }
    
    @Override
    public void switchProvider(String provider) {
        if (!providers.containsKey(provider)) {
            throw new ServiceException(400, "Unknown provider: " + provider);
        }
        
        this.currentProvider = provider;
        log.info("Switched to provider: {}", provider);
    }
    
    /**
     * 获取当前提供商
     */
    private LLMProvider getProvider() {
        LLMProvider provider = providers.get(currentProvider);
        if (provider == null) {
            throw new ServiceException(500, "Provider not initialized: " + currentProvider);
        }
        return provider;
    }
}

